package cs342.project1.mathNotebook.tests.expressions;

import java.lang.reflect.InvocationTargetException;

import junit.framework.Assert;

import org.junit.*;

import cs342.project1.mathNotebook.expressions.*;

/**
 * Tests the Expression factory.
 * 
 * @author Jared Schlicht
 * 
 */
public class ExprFactoryTests {

    private ExprFactory factory;

    @Before
    public void setUp() throws Exception {
	this.factory = new ExprFactory();
    }

    /**
     * Ensures a basic expression can be created (2+3)
     * 
     * @throws NoSuchMethodException
     * @throws ClassNotFoundException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws SecurityException
     * @throws IllegalArgumentException
     */
    @Test
    public void testCreateExpression() throws IllegalArgumentException,
	    SecurityException, InstantiationException, IllegalAccessException,
	    InvocationTargetException, ClassNotFoundException,
	    NoSuchMethodException {
	Expr lhs = new LiteralExpr(2.0);
	Expr rhs = new LiteralExpr(3.0);
	Object[] params = new Object[] { lhs, rhs };

	Expr addExpr = this.factory.createExpression("+", params);

	Assert.assertTrue("addExpr must not be null", addExpr != null);
	Assert.assertTrue("addExpr must be of type AddExpr",
		addExpr instanceof AddExpr);
    }

    /**
     * Tests the behavior of the operands method
     * @author Jared Schlicht
     */
    @Test
    public void testOperands() {
	Assert.assertEquals("Addition must have 2 operands", 2,
		this.factory.operands("+"));
    }
    
    /**
     * Tests behavior of isLeftAssociative method
     * @author Jared Schlicht
     */
    @Test
    public void testLeftAssoc() {
	Assert.assertFalse("Power must be right associative", this.factory.isLeftAssociative("^"));
    }
    
    /**
     * Tests behavior of the precedence method
     * @author Jared Schlicht
     */
    @Test
    public void testPrecedence() {
	Assert.assertEquals("Precedence of subtraction must be 1", 1, this.factory.precedence("-"));
    }
}
